package bingo.security.datasecurity.core;

import org.springframework.util.Assert;


/**
 * 2008-6-2  下午02:13:59 DataSecurityManager.java
 * Author:yangdongyu(yangdy@bingosoft.net)
 * ReadMe:
 * ChangeLog:
 */
public class DataSecurityManager {
	/**
	 * 规则定位器,根据传入的动作,解析出动作对应的规则
	 */
	private ISecurityRuleLocator ruleLocator;	
	/**
	 * 规则解析器,用于解析规则中特殊变量,如环境变量
	 */
	private ISecurityRuleParser ruleParser;
	/**
	 * 规则渲染器,用于渲染规则
	 */
	private ISecurityRuleRender ruleRender;
	
	
	/**
	 * 动作表达式中异常保留字
	 */
	private String exceptionKey = "!";

	public String getExceptionKey() {
		return exceptionKey;
	}

	public void setExceptionKey(String exceptionKey) {
		this.exceptionKey = exceptionKey;
	}

	public ISecurityRuleLocator getRuleLocator() {
		return ruleLocator;
	}

	public void setRuleLocator(ISecurityRuleLocator ruleLocator) {
		this.ruleLocator = ruleLocator;
	}

	public ISecurityRuleParser getRuleParser() {
		return ruleParser;
	}

	public void setRuleParser(ISecurityRuleParser parser) {
		this.ruleParser = parser;
	}	



	/**
	 * 查找动作对应的规则,并实现规则的解析
	 * @param action 动作的名称
	 * @return 和动作对应,并完成解析的规则
	 */
	public String resolve(String action){
		//参数检查
		Assert.notNull(action, "Action can not be null ...");
		String rule = null;
		//动作检查
		int startIndex = action.indexOf('(');
		int endIndex = action.indexOf(')');
		//解析和获取默认表达式
		String defaultExpression = null;
		if(startIndex > -1 && endIndex > -1 && startIndex < endIndex ){
			defaultExpression = action.substring(startIndex+1, endIndex);
		}
		if(this.ruleLocator != null){
			rule = ruleLocator.locate(action);
		}
		if(rule == null && defaultExpression != null){//没有对应的规则,检查默认表达式
			if(this.exceptionKey.equals(defaultExpression.trim())){
				throw new DataSecurityException(action,"您没有相应的数据权限执行动作 [" + action + "]...");
			}else if(defaultExpression.startsWith(exceptionKey)){
				throw new DataSecurityException(action,defaultExpression.substring(exceptionKey.length()));
			}else{
				return defaultExpression;
			}
		}
		//进行规则的解析
		if(this.ruleParser != null){
			rule = this.ruleParser.parseRule(action,rule);
		}
		if(this.ruleRender != null){
			rule = this.ruleRender.renderRule(action,rule);
		}
		return rule;
	}

	public ISecurityRuleRender getRuleRender() {
		return ruleRender;
	}

	public void setRuleRender(ISecurityRuleRender ruleRender) {
		this.ruleRender = ruleRender;
	}

}
